#pragma once

#include <vector>
#include <Eigen/Core>
#include "common.h"

struct RegionModel {
	struct DataPoint {
		Eigen::Vector3f center_f_body;
		Eigen::Vector3f normal_f_body;
		float foreground_distance = 0.0f;
		float background_distance = 0.0f;
	};

	struct View {
		std::vector<DataPoint> data_points;
		Eigen::Vector3f orientation;
		float contour_length;
	};

	std::vector<View> views_;

	int n_contour_points;
	int n_divides;

	bool GetClosestView(
		const Pose& body2camera_pose,
		const View** closest_view) const;
};

class Body;

class RegionModelBuilder {
public:
	RegionModel* Build(Body* body, const std::string& model_path);
	bool WriteModel(const std::string& model_path, RegionModel* region_model);
	bool LoadModel(const std::string& model_path, RegionModel* region_model);

	RegionModelBuilder& n_contour_points(int value) {
		n_contour_points_ = value;
		return *this;
	}

	RegionModelBuilder& n_divides(int value) {
		n_divides_ = value;
		return *this;
	}

	RegionModelBuilder& sphere_radius(float value) {
		sphere_radius_ = value;
		return *this;
	}

private:
	int n_divides_ = 4;
	int n_contour_points_ = 200;
	float sphere_radius_ = 0.8f;
	bool use_random_seed_ = false;
};